import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';

class MFadeOpacity extends ImplicitlyAnimatedWidget {
  /// Creates a widget that animates its opacity implicitly.
  ///
  /// The [opacity] argument must not be null and must be between 0.0 and 1.0,
  /// inclusive. The [curve] and [duration] arguments must not be null.
  const MFadeOpacity({
    Key key,
    this.child,
     this.opacity,
    Curve curve = Curves.linear,
     Duration duration,
  })  : assert(opacity != null && opacity >= 0.0 && opacity <= 1.0),
        super(key: key, curve: curve, duration: duration);

  /// The widget below this widget in the tree.
  ///
  /// {@macro flutter.widgets.child}
  final Widget child;

  /// The target opacity.
  ///
  /// An opacity of 1.0 is fully opaque. An opacity of 0.0 is fully transparent
  /// (i.e., invisible).
  ///
  /// The opacity must not be null.
  final double opacity;

  @override
  _MFadeOpacityState createState() => _MFadeOpacityState();

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DoubleProperty('opacity', opacity));
  }
}

class _MFadeOpacityState
    extends ImplicitlyAnimatedWidgetState<MFadeOpacity> {
  Tween<double> _opacity;
  Animation<double> _opacityAnimation;
  var _show = false;
  @override
  void forEachTween(TweenVisitor<dynamic> visitor) {
    _opacity = visitor(_opacity, widget.opacity,
        (dynamic value) => Tween<double>(begin: value));
  }
  listener(){
    if (_opacityAnimation.value == 0.0 && _show) {
        setState(() {
          _show = false;
        });
      } else if (_opacityAnimation.value > 0.0 && !_show) {
        setState(() {
          _show = true;
        });
      }
  }
  @override
  void didUpdateTweens() {
    _opacityAnimation = animation.drive(_opacity);
    _opacityAnimation.removeListener(listener);
    _opacityAnimation.addListener(listener);
  }

  @override
  Widget build(BuildContext context) {
    return Visibility(
      visible: _show,
      child: FadeTransition(opacity: _opacityAnimation, child: widget.child),
    );
  }
}
